<script lang="ts" setup>
import { getCurrentInstance, ref, watch } from 'vue';
import Dept from '~icons/ri/git-branch-line';
import More2Fill from '~icons/ri/more-2-fill';
import OfficeBuilding from '~icons/ep/office-building';
import LocationCompany from '~icons/ep/add-location';
import ExpandIcon from '@/assets/svg/expand.svg?component';
import UnExpandIcon from '@/assets/svg/unexpand.svg?component';
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
import Reset from '~icons/ri/restart-line';
import { buttonClass, defaultProps, onSearch, Tree } from '@/views/system/admin-user/utils';
import { useAdminUserStore } from '@/store/system/adminUser';
import { $t } from '@/plugins/i18n';

defineProps({
  treeLoading: Boolean,
  treeData: Array,
});

const emit = defineEmits(['tree-select']);

const adminUserStore = useAdminUserStore();
const treeRef = ref();
const isExpand = ref(true);
const searchValue = ref('');
const highlightMap = ref({});
const { proxy } = getCurrentInstance();

const filterNode = (value: string, data: Tree) => {
  if (!value) return true;
  return data.deptName.includes(value);
};

function nodeClick(value) {
  const nodeId = value.$treeNodeId;
  highlightMap.value[nodeId] = highlightMap.value[nodeId]?.highlight
    ? Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
        highlight: false,
      })
    : Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
        highlight: true,
      });
  Object.values(highlightMap.value).forEach((v: Tree) => {
    if (v.id !== nodeId) {
      v.highlight = false;
    }
  });
  emit(
    'tree-select',
    highlightMap.value[nodeId]?.highlight
      ? Object.assign({
          ...value,
          selected: true,
        })
      : Object.assign({ ...value, selected: false })
  );
}

function toggleRowExpansionAll(status) {
  isExpand.value = status;
  const nodes = (proxy.$refs['treeRef'] as any).store._getAllNodes();
  for (let i = 0; i < nodes.length; i++) {
    nodes[i].expanded = status;
  }
}

/** 重置部门树状态（选中状态、搜索框值、树初始化） */
function onTreeReset() {
  highlightMap.value = {};
  searchValue.value = '';
  adminUserStore.form.deptIds = undefined;
  toggleRowExpansionAll(true);
  onSearch();
}

watch(searchValue, (val) => {
  treeRef.value!.filter(val);
});

defineExpose({ onTreeReset });
</script>

<template>
  <div v-loading="treeLoading" :style="{ minHeight: `calc(100vh - 130px)` }" class="h-full bg-bg_color overflow-hidden relative">
    <div class="flex items-center h-[34px]">
      <el-input v-model="searchValue" :placeholder="$t('input') + $t('adminUser_dept')" class="ml-2" clearable size="small">
        <template #suffix>
          <el-icon class="el-input__icon">
            <IconifyIconOffline v-show="searchValue.length === 0" icon="ri/search-line" />
          </el-icon>
        </template>
      </el-input>
      <el-dropdown :hide-on-click="false">
        <IconifyIconOffline :icon="More2Fill" class="w-[28px] cursor-pointer" width="18px" />
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>
              <el-button
                :class="buttonClass"
                :icon="useRenderIcon(isExpand ? ExpandIcon : UnExpandIcon)"
                link
                type="primary"
                @click="toggleRowExpansionAll(!isExpand)"
              >
                {{ isExpand ? $t('fold_all') : $t('unfold_all') }}
              </el-button>
            </el-dropdown-item>
            <el-dropdown-item>
              <el-button :class="buttonClass" :icon="useRenderIcon(Reset)" link type="primary" @click="onTreeReset">
                {{ $t('buttons.reset') }}
              </el-button>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
    <el-divider />
    <el-scrollbar height="calc(90vh - 88px)">
      <el-tree
        ref="treeRef"
        :data="treeData"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
        :props="defaultProps"
        default-expand-all
        node-key="id"
        size="small"
        @node-click="nodeClick"
      >
        <template #default="{ node, data }">
          <div
            :class="[
              'rounded',
              'flex',
              'items-center',
              'select-none',
              'hover:text-primary',
              searchValue.trim().length > 0 && node.label.includes(searchValue) && 'text-red-500',
              highlightMap[node.id]?.highlight ? 'dark:text-primary' : '',
            ]"
            :style="{
              color: highlightMap[node.id]?.highlight ? 'var(--el-color-primary)' : '',
              background: highlightMap[node.id]?.highlight ? 'var(--el-color-primary-light-7)' : 'transparent',
            }"
          >
            <IconifyIconOffline :icon="data.type === 1 ? OfficeBuilding : data.type === 2 ? LocationCompany : Dept" />
            <span :title="node.label" class="!w-[120px] !truncate">
              {{ node.label }}
            </span>
          </div>
        </template>
      </el-tree>
    </el-scrollbar>
  </div>
</template>

<style lang="scss" scoped>
:deep(.el-divider) {
  margin: 0;
}

:deep(.el-tree) {
  --el-tree-node-hover-bg-color: transparent;
}
</style>
